//
//  TQQBollTagView.swift
//  SwiftLearning
//
//  Created by 黄龙 on 2024/1/29.
//

import UIKit

class TQQBollTagView: UIView {
    private var tagParams:[UIView] = []
    private var tagCoordinates:[XYZPoint] = []
    var timer:CADisplayLink?
    private var isPaned = false
    private var translation = CGPoint.zero
    private var lastPan = CGPoint.zero
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit{
        stopTimer()
        print("deinit.TQQBollTagView")
    }
    
    init(frame:CGRect,tags:[UIView]){
        super.init(frame: frame)
        self.tagParams.append(contentsOf: tags)
        for i in 0 ..< self.tagParams.count{
            self.addSubview(tagParams[i])
        }
        translation = CGPoint.init(x: 1, y: 0)
        
        initView()
    }
    
    func initView(){
        // 重置view的中心点,便于计算
        
        for perView in tagParams{
            perView.center = CGPoint(x: self.bounds.width/2.0, y: self.bounds.height/2.0)
        }
        let p1 = Double.pi * (3 - sqrt(5)); //5开平方根
        let p2 = 2.0 / Double(tagParams.count)
        NSLog("p1:%f p2:%f", p1, p2)
        for i in 0 ..< tagParams.count{
            let y = Double(i) * p2 - 1.0 + (p2 / 2.0)
            let r = sqrt(Double(1 - y*y))
            let p3 = Double(i) * p1
            let x = cos(p3) * r
            let z = sin(p3) * r
            let point = XYZPoint(x: x,y: CGFloat(y),z: z)
            tagCoordinates.append(point)
            NSLog("x:%f y:%f z:%f", point.x, point.y, point.z)
            let time = CGFloat((arc4random_uniform(10) + 10)) / 20.0
            UIView.animate(withDuration: time, delay: 0,options: [.curveEaseInOut]) {[weak self] in
//动画将tag从默认的中心位置移到球面上
                self?.setViewWith(coordinate: point, at: i)
            }
        }
        
        let pan = UIPanGestureRecognizer.init(target: self, action: #selector(panAction(_:)))
        self.addGestureRecognizer(pan)

    }
    
    func autoAnimate(){
        startTimer()
    }
    
}

//初始化后自动旋转
extension TQQBollTagView{
    func changeCoordinate(point: XYZPoint) -> CGPoint {
        let x = (point.x + 1.0) / 2.0 * self.bounds.width
        let y = (point.y + 1.0) / 2.0 * self.bounds.height
        return CGPoint.init(x: x, y: y)
    }
    
    func setViewWith(coordinate : XYZPoint, at index: Int) {
        let tagView = tagParams[index]
        tagView.center = changeCoordinate(point: coordinate)
        tagView.layer.zPosition = coordinate.z + 1
        let scale = (coordinate.z + 2.0) / 3.0      //0.3~1
        tagView.transform = CGAffineTransform.init(scaleX: scale, y: scale)
        tagView.alpha = scale
        tagView.isUserInteractionEnabled = coordinate.z > 0
        
    }
    
    func rotateWith(translation: CGPoint) {
        var translation = translation
        translation.x /= self.bounds.width / 2.0
        translation.y /= self.bounds.height / 2.0
        
        for item in tagCoordinates.enumerated() {
            var location = item.element
            location.rotate(translation: translation)
            tagCoordinates[item.offset] = location
            setViewWith(coordinate: location, at: item.offset)
        }
        
    }
    
    @objc func autoTurnRotation(){
//        DispatchQueue.main.async{[weak self] in //照旧是不能deinit，因为已经是强引用了self.autoTurnRotation，内存泄漏
//            if let self = self{
                if self.isPaned {
                    let distance = sqrt(pow(self.translation.x, 2) + pow(self.translation.y, 2))
                    if distance > 1 {
                        let scale: CGFloat = 0.9
                        self.translation.x *= scale
                        self.translation.y *= scale
                        self.rotateWith(translation: self.translation)
                    } else {
                        self.isPaned = false
                    }
                }
                self.rotateWith(translation: CGPoint.init(x: self.translation.x, y: self.translation.y))
//            }
//        }
    }
    
    func startTimer(){
//        DispatchQueue.main.async{[weak self] in //也不行，仍旧不会deinit,
//            if let self = self{
                self.timer = CADisplayLink(target: self, selector: #selector(self.autoTurnRotation)) //此种写法强引用了self会导致退出时不能触发deinit
                if let timer = self.timer{
                    timer.add(to: RunLoop.main, forMode: .default)
                }
//            }
//        }
    }
    func stopTimer(){
        if let timer = timer{
            timer.invalidate()
            self.timer = nil
        }
    }

}

extension TQQBollTagView{
//手滑动方向旋转
    @objc func panAction(_ pan: UIPanGestureRecognizer) {
        if pan.state == .began {
            lastPan = pan.translation(in: self)
            timer?.isPaused = true
        }
        else if pan.state == .changed {
            let current = pan.translation(in: self)
            translation = CGPoint.init(x: current.x - lastPan.x, y: current.y - lastPan.y)
            rotateWith(translation: translation)
            lastPan = current
        }
        else if pan.state == .ended {
            
            isPaned = true
            timer?.isPaused = false
            
        }
        
    }
}
